// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.erosion.categories;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import zombie.erosion.ErosionData;
import zombie.erosion.obj.ErosionObj;
import zombie.erosion.obj.ErosionObjSprites;
import zombie.erosion.season.ErosionIceQueen;
import zombie.iso.IsoGridSquare;
import zombie.iso.IsoObject;
import zombie.iso.sprite.IsoSprite;

public final class NatureTrees extends ErosionCategory {
    private final int[][] soilRef = new int[][]{
        {2, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5},
        {1, 1, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5},
        {2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 3, 3, 4, 4, 4, 5},
        {1, 7, 7, 7, 9, 9, 9, 9, 9, 9, 9},
        {2, 2, 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9},
        {1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 7, 7, 7, 9},
        {1, 2, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 6},
        {1, 1, 2, 2, 3, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6},
        {1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 8, 8, 8, 6},
        {3, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11},
        {1, 1, 3, 3, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11},
        {1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 10, 10, 10, 11}
    };
    private final NatureTrees.TreeInit[] trees = new NatureTrees.TreeInit[]{
        new NatureTrees.TreeInit("American Holly", "e_americanholly_1", true),
        new NatureTrees.TreeInit("Canadian Hemlock", "e_canadianhemlock_1", true),
        new NatureTrees.TreeInit("Virginia Pine", "e_virginiapine_1", true),
        new NatureTrees.TreeInit("Riverbirch", "e_riverbirch_1", false),
        new NatureTrees.TreeInit("Cockspur Hawthorn", "e_cockspurhawthorn_1", false),
        new NatureTrees.TreeInit("Dogwood", "e_dogwood_1", false),
        new NatureTrees.TreeInit("Carolina Silverbell", "e_carolinasilverbell_1", false),
        new NatureTrees.TreeInit("Yellowwood", "e_yellowwood_1", false),
        new NatureTrees.TreeInit("Eastern Redbud", "e_easternredbud_1", false),
        new NatureTrees.TreeInit("Redmaple", "e_redmaple_1", false),
        new NatureTrees.TreeInit("American Linden", "e_americanlinden_1", false)
    };
    private int[] spawnChance = new int[100];
    private ArrayList<ErosionObj> objs = new ArrayList();

    @Override
    public boolean replaceExistingObject(
        IsoGridSquare _sq, ErosionData.Square _sqErosionData, ErosionData.Chunk _chunkData, boolean _isExterior, boolean _hasWall
    ) {
        int int0 = _sq.getObjects().size();

        for (int int1 = int0 - 1; int1 >= 1; int1--) {
            IsoObject isoObject = _sq.getObjects().get(int1);
            IsoSprite isoSprite = isoObject.getSprite();
            if (isoSprite != null && isoSprite.getName() != null) {
                if (isoSprite.getName().startsWith("jumbo_tree_01")) {
                    int int2 = _sqErosionData.soil;
                    if (int2 < 0 || int2 >= this.soilRef.length) {
                        int2 = _sqErosionData.rand(_sq.x, _sq.y, this.soilRef.length);
                    }

                    int[] int3 = this.soilRef[int2];
                    int int4 = _sqErosionData.noiseMainInt;
                    NatureTrees.CategoryData categoryData0 = (NatureTrees.CategoryData)this.setCatModData(_sqErosionData);
                    categoryData0.gameObj = int3[_sqErosionData.rand(_sq.x, _sq.y, int3.length)] - 1;
                    categoryData0.maxStage = 5 + (int)Math.floor((double)((float)int4 / 51.0F)) - 1;
                    categoryData0.stage = categoryData0.maxStage;
                    categoryData0.spawnTime = 0;
                    categoryData0.dispSeason = -1;
                    ErosionObj erosionObj0 = (ErosionObj)this.objs.get(categoryData0.gameObj);
                    isoObject.setName(erosionObj0.name);
                    categoryData0.hasSpawned = true;
                    return true;
                }

                if (isoSprite.getName().startsWith("vegetation_trees")) {
                    int int5 = _sqErosionData.soil;
                    if (int5 < 0 || int5 >= this.soilRef.length) {
                        int5 = _sqErosionData.rand(_sq.x, _sq.y, this.soilRef.length);
                    }

                    int[] int6 = this.soilRef[int5];
                    int int7 = _sqErosionData.noiseMainInt;
                    NatureTrees.CategoryData categoryData1 = (NatureTrees.CategoryData)this.setCatModData(_sqErosionData);
                    categoryData1.gameObj = int6[_sqErosionData.rand(_sq.x, _sq.y, int6.length)] - 1;
                    categoryData1.maxStage = 3 + (int)Math.floor((double)((float)int7 / 51.0F)) - 1;
                    categoryData1.stage = categoryData1.maxStage;
                    categoryData1.spawnTime = 0;
                    categoryData1.dispSeason = -1;
                    ErosionObj erosionObj1 = (ErosionObj)this.objs.get(categoryData1.gameObj);
                    isoObject.setName(erosionObj1.name);
                    categoryData1.hasSpawned = true;
                    return true;
                }

                for (int int8 = 0; int8 < this.trees.length; int8++) {
                    if (isoSprite.getName().startsWith(this.trees[int8].tile)) {
                        NatureTrees.CategoryData categoryData2 = (NatureTrees.CategoryData)this.setCatModData(_sqErosionData);
                        categoryData2.gameObj = int8;
                        categoryData2.maxStage = 3;
                        categoryData2.stage = categoryData2.maxStage;
                        categoryData2.spawnTime = 0;
                        _sq.RemoveTileObject(isoObject);
                        return true;
                    }
                }
            }
        }

        return false;
    }

    @Override
    public boolean validateSpawn(
        IsoGridSquare _sq, ErosionData.Square _sqErosionData, ErosionData.Chunk _chunkData, boolean _isExterior, boolean _hasWall, boolean _isRespawn
    ) {
        if (_sq.getObjects().size() > (_hasWall ? 2 : 1)) {
            return false;
        } else if (_sqErosionData.soil >= 0 && _sqErosionData.soil < this.soilRef.length) {
            int[] int0 = this.soilRef[_sqErosionData.soil];
            int int1 = _sqErosionData.noiseMainInt;
            int int2 = this.spawnChance[int1];
            if (int2 > 0 && _sqErosionData.rand(_sq.x, _sq.y, 101) < int2) {
                NatureTrees.CategoryData categoryData = (NatureTrees.CategoryData)this.setCatModData(_sqErosionData);
                categoryData.gameObj = int0[_sqErosionData.rand(_sq.x, _sq.y, int0.length)] - 1;
                categoryData.maxStage = 2 + (int)Math.floor((double)((int1 - 50) / 17)) - 1;
                categoryData.stage = 0;
                categoryData.spawnTime = 30 + (100 - int1);
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    @Override
    public void update(IsoGridSquare _sq, ErosionData.Square _sqErosionData, ErosionCategory.Data _sqCategoryData, ErosionData.Chunk _chunkData, int _eTick) {
        NatureTrees.CategoryData categoryData = (NatureTrees.CategoryData)_sqCategoryData;
        if (_eTick >= categoryData.spawnTime && !categoryData.doNothing) {
            if (categoryData.gameObj >= 0 && categoryData.gameObj < this.objs.size()) {
                ErosionObj erosionObj = (ErosionObj)this.objs.get(categoryData.gameObj);
                int int0 = categoryData.maxStage;
                int int1 = (int)Math.floor((double)((float)(_eTick - categoryData.spawnTime) / ((float)erosionObj.cycleTime / ((float)int0 + 1.0F))));
                if (int1 < _sqCategoryData.stage) {
                    int1 = _sqCategoryData.stage;
                }

                if (int1 > int0) {
                    int1 = int0;
                }

                boolean boolean0 = true;
                int int2 = this.currentSeason(_sqErosionData.magicNum, erosionObj);
                boolean boolean1 = false;
                this.updateObj(_sqErosionData, _sqCategoryData, _sq, erosionObj, boolean0, int1, int2, boolean1);
            } else {
                this.clearCatModData(_sqErosionData);
            }
        }
    }

    @Override
    public void init() {
        for (int int0 = 0; int0 < 100; int0++) {
            this.spawnChance[int0] = int0 >= 50 ? (int)this.clerp((float)(int0 - 50) / 50.0F, 0.0F, 90.0F) : 0;
        }

        int[] int1 = new int[]{0, 5, 1, 2, 3, 4};
        this.seasonDisp[5].season1 = 0;
        this.seasonDisp[5].season2 = 0;
        this.seasonDisp[5].split = false;
        this.seasonDisp[1].season1 = 1;
        this.seasonDisp[1].season2 = 0;
        this.seasonDisp[1].split = false;
        this.seasonDisp[2].season1 = 2;
        this.seasonDisp[2].season2 = 3;
        this.seasonDisp[2].split = true;
        this.seasonDisp[4].season1 = 4;
        this.seasonDisp[4].season2 = 0;
        this.seasonDisp[4].split = true;
        String string0 = null;
        ErosionIceQueen erosionIceQueen = ErosionIceQueen.instance;

        for (int int2 = 0; int2 < this.trees.length; int2++) {
            String string1 = this.trees[int2].name;
            String string2 = this.trees[int2].tile;
            boolean _boolean = !this.trees[int2].evergreen;
            ErosionObjSprites erosionObjSprites = new ErosionObjSprites(6, string1, true, false, _boolean);

            for (int int3 = 0; int3 < 6; int3++) {
                for (int int4 = 0; int4 < int1.length; int4++) {
                    if (int3 > 3) {
                        int int5 = 0 + int4 * 2 + (int3 - 4);
                        if (int4 == 0) {
                            string0 = string2.replace("_1", "JUMBO_1") + "_" + int5;
                            erosionObjSprites.setBase(int3, string0, 0);
                        } else if (int4 == 1) {
                            erosionIceQueen.addSprite(string0, string2.replace("_1", "JUMBO_1") + "_" + int5);
                        } else if (_boolean) {
                            erosionObjSprites.setChildSprite(int3, string2.replace("_1", "JUMBO_1") + "_" + int5, int1[int4]);
                        }
                    } else {
                        int int6 = 0 + int4 * 4 + int3;
                        if (int4 == 0) {
                            string0 = string2 + "_" + int6;
                            erosionObjSprites.setBase(int3, string0, 0);
                        } else if (int4 == 1) {
                            erosionIceQueen.addSprite(string0, string2 + "_" + int6);
                        } else if (_boolean) {
                            erosionObjSprites.setChildSprite(int3, string2 + "_" + int6, int1[int4]);
                        }
                    }
                }
            }

            ErosionObj erosionObj = new ErosionObj(erosionObjSprites, 60, 0.0F, 0.0F, true);
            this.objs.add(erosionObj);
        }
    }

    @Override
    protected ErosionCategory.Data allocData() {
        return new NatureTrees.CategoryData();
    }

    @Override
    public void getObjectNames(ArrayList<String> list) {
        for (int _int = 0; _int < this.objs.size(); _int++) {
            if (((ErosionObj)this.objs.get(_int)).name != null && !list.contains(((ErosionObj)this.objs.get(_int)).name)) {
                list.add(((ErosionObj)this.objs.get(_int)).name);
            }
        }
    }

    private static final class CategoryData extends ErosionCategory.Data {
        public int gameObj;
        public int maxStage;
        public int spawnTime;

        @Override
        public void save(ByteBuffer byteBuffer) {
            super.save(byteBuffer);
            byteBuffer.put((byte)this.gameObj);
            byteBuffer.put((byte)this.maxStage);
            byteBuffer.putShort((short)this.spawnTime);
        }

        @Override
        public void load(ByteBuffer byteBuffer, int _int) {
            super.load(byteBuffer, _int);
            this.gameObj = byteBuffer.get();
            this.maxStage = byteBuffer.get();
            this.spawnTime = byteBuffer.getShort();
        }
    }

    private class TreeInit {
        public String name;
        public String tile;
        public boolean evergreen;

        public TreeInit(String string0, String string1, boolean _boolean) {
            this.name = string0;
            this.tile = string1;
            this.evergreen = _boolean;
        }
    }
}
